package com.miyu.client1.test.magic;

import us.codecraft.webmagic.*;
import us.codecraft.webmagic.pipeline.ConsolePipeline;
import us.codecraft.webmagic.pipeline.Pipeline;
import us.codecraft.webmagic.processor.PageProcessor;

import java.io.File;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;

public class demo implements PageProcessor {
    public void process(Page page) {
        String url=page.getUrl().get();//得到url，起始为http://www.147xs.org/
        //通过分析知道带有html的url是之前获取到的章节的链接。
        if(url.contains(".html")) {//如果是章节的链接则进入
            this.getContent(page);//抓取内容函数
        }else if(url.equals("http://www.147xs.org/")){//如果是网站首页则进入，获取所有小说的链接
            List<String> links = page.getHtml().links().regex(".*book/\\d+/").all();
            page.addTargetRequests(links);
            page.setSkip(true);
        } else {
            //获取该小说的所有章节的链接
            List<String> links = page.getHtml().links().regex(".*\\d+\\.html").all();
            page.addTargetRequests(links);
            page.setSkip(true);
        }
    }
    public void getContent(Page page){
        //书名
        String bookname=page.getHtml().xpath("//div[@class='con_top']/a[3]/text()").get();
        //标题
        String title=page.getHtml().xpath("//div[@class='bookname']/h1/text()").get();
        //内容
        List<String> all = page.getHtml().xpath("//div[@id='content']//p/text()").all();
        //通过键值对的方式存入，用于后面写入文件时用到这些属性
        page.putField("bookname",bookname);
        page.putField("title",title.replaceAll("[/?\\\\]",""));
        page.putField("content",all);
    }
    private Site site = Site.me().setCharset("utf8").
            setTimeOut(10000).
            setRetryTimes(5).
            setCycleRetryTimes(3);
    public Site getSite() {
        return site;
    }

    public static void main(String[] args) {
        String startUrl="http://www.147xs.org/";
        Spider.create(new demo()).addUrl(startUrl)
                .addPipeline(new SavePipeline())
                .addPipeline(new ConsolePipeline())
                .thread(50)
                    .run();
    }
}

/**
 * 自定义管道类
 * 用于保存爬取的小说到文件
 */
class SavePipeline implements Pipeline {
    public void process(ResultItems resultItems, Task task) {
        //通过key获取值
        String bookname=resultItems.get("bookname");
        String title = resultItems.get("title");
        List<String> contents=resultItems.get("content");
        //创建小说目录
        File file=new File("网络小说\\"+bookname);
        if(!file.exists()){
            file.mkdirs();
        }
        //写入文件
        try {
            FileOutputStream writer=new FileOutputStream(
                    file.getAbsolutePath()+"\\"+title+".txt");
            //遍历集合，取出每段内容
            for (String content : contents) {
                String replace = content.replace("。", "\n");
                writer.write(replace.getBytes(StandardCharsets.UTF_8));
            }
            writer.flush();
            writer.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
